Discover your Poppy Ergo Jr

This notebook will guide you in your very first steps with Poppy Ergo Jr in Python.

What you will see in this notebook:

  1. Instantiate your robot
  2. Access motors, send motor commands
  3. Read sensor value
  4. Start high level behaviors

We assume here that you are connected to a physical Poppy Ergo Jr. It also need to be assembled and configured (you can referer to the documentation if you haven't done in yet). You can use any tool. For the sensor section, you will also need to have connected the camera.


In [ ]:
# Import some matplolib and numpy shortcuts for Jupyter notebook
%matplotlib inline
from __future__ import print_function

import numpy as np
import matplotlib.pyplot as plt

Instantiate your robot

To start using your robot in Python, you first need to instantiate it. You can do that by running the following code:


In [ ]:
from pypot.creatures import PoppyErgoJr

poppy = PoppyErgoJr()

# If you want to use the robot with the camera unpluged, 
# you have to pass the argument camera='dummy
# poppy = PoppyErgoJr(camera='dummy')

# If you want to use a simulated robot in the 3D web viewer aka "poppy simu"
# poppy = PoppyErgoJr(simulator='poppy-simu')
# then go to http://simu.poppy-project.org/poppy-ergo-jr/ and check "synchroniser"

# If you want to use the robot with V-REP simulator, open V-REP and execute :
# poppy = PoppyErgoJr(simulator='vrep')
# You can also change the end effector tools if you precise the V-REP scene
# poppy = PoppyErgoJr(simulator='vrep', scene="poppy_ergo_jr_holder.ttt")
# poppy = PoppyErgoJr(simulator='vrep', scene="poppy_ergo_jr_empty.ttt")

This creates a Robot object that can be used to access the motors and sensors. It handles all the low-level communication for you, so you do not need to know anything about the serial protocol used to make a motor turn. The motors and sensors fields of the Robot are automatically synced to match the state of their hardware equivalent.

Before doing anything else, we will initalize everything by asking the robot to go to its rest position (the code below will be described in more detailed later):


In [ ]:
poppy.rest_posture.start()

Access motors

In a Poppy Ergo Jr, the motor are defined as illustrated below:

From the Robot object, you can directly retrieve the list of motors connected:


In [ ]:
poppy.motors

As you can see poppy.motors holds a list of all motors.

You can retrieve all motors name:


In [ ]:
for m in poppy.motors:
    print(m.name)

Each of them can be access directly from its name. For instance:


In [ ]:
poppy.m1

Read values from the motors

From the motor object you can access its registers. The main ones are:

  • present_position: the current position of the motor in degrees
  • present_speed: the current speed of the motor in degrees per second
  • present_load: the current workload of the motor (in percentage of max load)
  • present_temperature: the temperature of the motor in celsius
  • angle_limit: the reachable limits of the motor (in degrees)

They can be accessed directly:


In [ ]:
poppy.m1.present_temperature

Or, to get the present position for all motors:


In [ ]:
[m.present_position for m in poppy.motors]

It's important to understand the poppy.m1.present_position is automatically updated with the real motor position (at 50Hz). Similarly for other registers, the update frequency may vary depending on its importance. For instance, the temperature is only refreshed at 1Hz as it is not fluctuating that quickly.

Send motor commands

On top of the registers presented above, they are additional ones used to send commands. For instance, the position of the motor is split in two different registers:

  • the read-only present_position of the motor
  • the read-write goal_position which sends to the motor a target position that it will try to reach.

If you want to set a new position for a motor, you write:


In [ ]:
poppy.m1.goal_position = 20

You should see the robot turn of 20 degrees. Sending motor command is as simple as that. To make it turn to the other side:


In [ ]:
poppy.m1.goal_position = -20

In the examples above, the motor turned as fast as possible (its default mode). You can change its moving_speed (i.e. its maximum possible speed):


In [ ]:
poppy.m1.moving_speed = 50

Now the motor m1 can not move faster than 50 degrees per second. If we ask to move again, you should see the difference:


In [ ]:
poppy.m1.goal_position = 90

The main write registers are:

  • goal_position: target position in degrees
  • moving_speed: maximum reachable speed in degrees per second
  • compliant (explained below)

The dynamixel servo motors have two modes:

  • stiff: the normal mode for motors where they can be controlled
  • compliant: a mode where the motors can be freely moved by hand. This is particularly useful for phyisical human-robot interaction

You can make them switch from one mode to the other using the compliant register. For instance, you can turn the motor m6 compliant via:


In [ ]:
poppy.m6.compliant = True

You should now be able to move this motors by hand. This is particularly useful for programming your robot by demonstration (see the dedicated notebook).

And to turn it stiff again:


In [ ]:
poppy.m6.compliant = False

Control motors LED

The XL-320 motors used in the Poppy Ergo Jr robot have a small colored LED. You can change its color programatically directly using pypot. This can be a great way to make your robot more lively, customized and expressive.

If you want to turn on the LED of the first motor and make it green you simply have to run:


In [ ]:
poppy.m1.led = 'green'

And to turn it off again:


In [ ]:
poppy.m1.led = 'off'

Obviously you can also do some more complex LED blinking. For instance:


In [ ]:
import time

for m in poppy.motors:
    time.sleep(0.5)
    m.led = 'yellow'
    time.sleep(1.0)
    m.led = 'off'

You can retrieve all available LED colors using:


In [ ]:
from pypot.dynamixel.conversion import XL320LEDColors

print(list(XL320LEDColors))

Read sensors

Reading sensor is exactly the same as reading registers from your robot. The sensors can be accessed via:


In [ ]:
poppy.sensors

Here, we have 2 sensors:

  • a camera
  • a marker detector

They can be accessed via their name:


In [ ]:
poppy.camera

You can retrieve all the existing registers of a sensor:


In [ ]:
poppy.camera.registers

And for instance to retrieve and displayed an image from the camera:


In [ ]:
img = poppy.camera.frame
plt.imshow(img)

Similarly to motors, the sensors values are automatically synchronized in background with the physical sensors. If you run again the previous code, you will see a more recent image:


In [ ]:
plt.imshow(poppy.camera.frame)

High level behaviors

The Poppy Ergo Jr robot comes with a set of pre-defined behaviors. They can be specific postures - such as the rest posture used at the beginning - or a dance, ...

You can find the exhaustive list using the primitives accessor:


In [ ]:
[p.name for p in poppy.primitives]

Those behaviors (or primitives in "poppy terms") can be started, stopped, paused, etc...


In [ ]:
poppy.tetris_posture.start()

You can make the Poppy Ergo Jr dance for 10 seconds:


In [ ]:
import time

poppy.dance.start()
time.sleep(10)
poppy.dance.stop()

Going further

Now that you have learnt the basis of what you can do with a Poppy Ergo Jr, there is much more to discover:

  • how to record/replay move by demonstration
  • how to define your own high-level behavior (e.g. a visual servoing of the tip of the robot using blob detection)
  • used your Poppy Ergo Jr as a connected device and make it communaticate with the rest of the world using HTTP requests
  • ...

You can find other examples in the docs or in the notebook folder next to this one.